package com.example.demo.Controller.UserInfo;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.Entity.User.User;
import com.example.demo.ServiceImpl.User.UserServiceImpl;
import com.example.demo.ServiceImpl.UserInfo.UserinfoServiceImpl;
import com.example.demo.Entity.UserInfo.Userinfo;
import com.example.demo.Utils.JWTUtils.JWTUtils;
import com.example.demo.Utils.RedisUtils.RedisUtil;
import com.example.demo.Utils.Result.R;
import io.micrometer.common.util.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@CrossOrigin(origins = "*")
@Slf4j
@RequestMapping("/userinfo")
@Tag(name = "UserinfoController", description = "UserinfoController 相关接口")
public class UserinfoController {

    @Resource
    private UserinfoServiceImpl userinfoService;

    @Resource
    private UserServiceImpl userService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping("/saveUserForm")
    @Transactional(rollbackFor = Exception.class)
    public Boolean SaveUserForm(@RequestBody Map<String, String> UserForm) {
        redisUtil.deleteKeysStartingWith("userinfo");
        redisUtil.deleteKeysStartingWith("user");
        String uid = UserForm.get("userId");
        String phone = UserForm.get("phone");
        String email = UserForm.get("email");
        String sex = UserForm.get("sex");
        String avatar = UserForm.get("avatar");
        String password = UserForm.get("password");
        String nickname = UserForm.get("nickname");
        String username = UserForm.get("username");
        String role = UserForm.get("role");
        if (uid == null) {
            User user = new User();
            user.setUsername(username);
            user.setPassword(new BCryptPasswordEncoder().encode(password));
            user.setLastLoginTime(new Date());
            user.setRole(role);
            if (userService.save(user)) {
                Integer userId = user.getUserId();
                log.info("用户注册成功，用户ID为：{}", userId);
                Userinfo userinfo = new Userinfo();
                userinfo.setUserId(userId);
                userinfo.setPhone(phone);
                userinfo.setEmail(email);
                userinfo.setNickname(nickname);
                userinfo.setAvatar(avatar);
                userinfo.setSex(sex);
                userinfoService.save(userinfo);
            }
        } else {
            Integer userId = Integer.parseInt(uid);
            User user = userService.getById(userId);
            if (user == null) {
                return false;
            }
            if (username != null) {
                user.setUsername(username);
            }
            if (password != null) {
                PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
                String encodePassword = passwordEncoder.encode(password);
                user.setPassword(encodePassword);
            }
            if (role != null) {
                user.setRole(role);
            }
            userService.updateById(user);
            LambdaQueryWrapper<Userinfo> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(Userinfo::getUserId, userId);
            Userinfo userinfo = userinfoService.getOne(queryWrapper);
            if (userinfo == null) {
                return false;
            }
            if (email != null) {
                userinfo.setEmail(email);
            }
            if (phone != null) {
                userinfo.setPhone(phone);
            }
            if (sex != null) {
                userinfo.setSex(sex);
            }
            if (avatar != null) {
                userinfo.setAvatar(avatar);
            }
            if (nickname != null) {
                userinfo.setNickname(nickname);
            }
            userinfoService.updateById(userinfo);

        }
        return true;
    }

    @PostMapping
    @Operation(summary = "保存或更新 Userinfo 信息", description = "根据传入的 Userinfo 对象保存或更新信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "保存或更新成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean save(@RequestBody Userinfo userinfo) {
// 保存或更新数据后，删除相关缓存
        redisTemplate.delete("userinfo:all");
        return userinfoService.saveOrUpdate(userinfo);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "根据 ID 删除 Userinfo 信息", description = "根据传入的 ID 删除对应的 Userinfo 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "删除成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean delete(@PathVariable(value = "id") Integer id) {
// 删除数据后，删除相关缓存
        redisTemplate.delete("userinfo:all");
        redisTemplate.delete("userinfo:id:" + id);
        return userinfoService.removeById(id);
    }

    @GetMapping("/getInfo")
    @Operation(summary = "根据token返回用户信息", description = "常用于登陆后逻辑")
    public R getInfo(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Integer userId = Integer.parseInt(JWTUtils.getUserIDFromToken(token));
        LambdaQueryWrapper<Userinfo> userinfoLambdaQueryWrapper = Wrappers.lambdaQuery();
        userinfoLambdaQueryWrapper.eq(Userinfo::getUserId, userId);
        Userinfo userinfo = userinfoService.getOne(userinfoLambdaQueryWrapper);
        return R.ok().put("userInfo", userinfo).put("Role", userService.getById(userId).getRole());
    }

    @GetMapping
    @Operation(summary = "获取所有 Userinfo 信息", description = "获取所有 Userinfo 的列表信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    public R findAll() {
        String key = "userinfo:all";
        @SuppressWarnings("unchecked")
        List<Userinfo> userinfoList = (List<Userinfo>) redisTemplate.opsForValue().get(key);
        if (userinfoList == null) {
            userinfoList = userinfoService.list();
            redisTemplate.opsForValue().set(key, userinfoList, 60, TimeUnit.MINUTES);
        }
        return R.ok().put("userinfoList", userinfoList);
    }

    @GetMapping("/{userId}")
    @Operation(summary = "根据用户ID获取完整用户信息", description = "获取用户基础信息和扩展信息")
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    public R getUserDetail(@PathVariable Integer userId) {
        User user = userService.getById(userId);
        LambdaQueryWrapper<Userinfo> userinfoLambdaQueryWrapper = Wrappers.lambdaQuery();
        userinfoLambdaQueryWrapper.eq(Userinfo::getUserId, userId);
        Userinfo userinfo = userinfoService.getOne(userinfoLambdaQueryWrapper); // 假设存在该方法
        return R.ok()
                .put("user", user)
                .put("userinfo", userinfo);
    }


    @GetMapping("/page")
    @Operation(summary = "分页查询用户信息（支持模糊搜索）", description = "根据页码、每页数量和搜索条件查询用户信息")
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "查询成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    @Parameter(name = "pageNum", in = ParameterIn.QUERY, description = "页码", required = true)
    @Parameter(name = "pageSize", in = ParameterIn.QUERY, description = "每页数量", required = true)
    @Parameter(name = "keyword", in = ParameterIn.QUERY, description = "搜索关键词（用户名/昵称）", required = false)
    public R findPage(
            @RequestParam(value = "pageNum") Integer pageNum,
            @RequestParam(value = "pageSize") Integer pageSize,
            @RequestParam(value = "keyword", required = false) String keyword
    ) {
        LambdaQueryWrapper<Userinfo> userLambdaQueryWrapper = Wrappers.lambdaQuery();
        userLambdaQueryWrapper.orderByDesc(Userinfo::getUserInfoId);
        if (StringUtils.isNotBlank(keyword)) {
            userLambdaQueryWrapper.like(Userinfo::getNickname, keyword)
                    .or().like(Userinfo::getEmail, keyword)
                    .or().like(Userinfo::getPhone, keyword);
        }
        Page<Userinfo> userinfoPage = userinfoService.page(new Page<>(pageNum, pageSize), userLambdaQueryWrapper);
        List<Userinfo> userinfoList = userinfoPage.getRecords();
        List<User> userList = new ArrayList<>();
        for (Userinfo userinfo : userinfoList) {
            Integer userId = userinfo.getUserId();
            User user = userService.getById(userId);
            userList.add(user);
        }
        return R.ok().put("userinfoPage", userinfoPage).put("userList", userList);
    }

    @PutMapping("/updateUserProfileForm")
    public R updateUserProfileForm(@RequestBody Map<String, Object> userProfileForm, HttpServletRequest request) {
        Integer userId = Integer.parseInt(JWTUtils.getUserIDFromToken(request.getHeader("Authorization")));
        LambdaQueryWrapper<Userinfo> userinfoLambdaQueryWrapper = Wrappers.lambdaQuery();
        userinfoLambdaQueryWrapper.eq(Userinfo::getUserId, userId);
        Userinfo userinfo = userinfoService.getOne(userinfoLambdaQueryWrapper);
        String nickname = (String) userProfileForm.get("name");
        String email = (String) userProfileForm.get("email");
        String phone = (String) userProfileForm.get("phone");
        String avatar = (String) userProfileForm.get("avatar");
        String sex = (String) userProfileForm.get("sex");
        if (userinfo != null) {
            if (nickname != null) {
                userinfo.setNickname(nickname);
            }
            if (email != null) {
                userinfo.setEmail(email);
            }
            if (phone != null) {
                userinfo.setPhone(phone);
            }
            if (avatar != null) {
                userinfo.setAvatar(avatar);
            }
            if (sex != null) {
                userinfo.setSex(sex);
            }
            userinfoService.updateById(userinfo);
        }
        return R.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/register")
    public R register(@RequestBody Map<String, Object> userProfileForm) {
        String username = (String) userProfileForm.get("username");
        String password = (String) userProfileForm.get("password");
        String nickname = (String) userProfileForm.get("nickname");
        String email = (String) userProfileForm.get("email");
        String phone = (String) userProfileForm.get("phone");
        String avatar = (String) userProfileForm.get("avatar");
        String sex = (String) userProfileForm.get("sex");
        String confirmPassword = (String) userProfileForm.get("confirmPassword");
        if (username == null || username.isEmpty() || password == null || password.isEmpty() || nickname == null || nickname.isEmpty() || email == null || email.isEmpty() || phone == null || phone.isEmpty() || sex == null || sex.isEmpty() || avatar == null || avatar.isEmpty() || confirmPassword == null || confirmPassword.isEmpty()) {
            return R.error("请填写完整的注册信息");
        }
        if (!password.equals(confirmPassword)) {
            return R.error("两次输入的密码不一致");
        }
        String CryptPassword = new BCryptPasswordEncoder().encode(password);
        User user = new User();
        user.setUsername(username);
        user.setPassword(CryptPassword);
        user.setLastLoginTime(new Date());
        user.setRole("USER");
        if (userService.save(user)) {
            Integer userId = user.getUserId();
            Userinfo userinfo = new Userinfo();
            userinfo.setUserId(userId);
            userinfo.setNickname(nickname);
            userinfo.setEmail(email);
            userinfo.setPhone(phone);
            userinfo.setAvatar(avatar);
            userinfo.setSex(sex);
            userinfoService.save(userinfo);
        }
        return R.ok();
    }
}